﻿using Inventorycount.API.Write.Application.Command;
using Inventorycount.Domain;
using Inventorycount.ErrorCode;
using MediatR;
using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Inventorycount.API.Write.Application.CommandHandLer
{
    public class UpdateoutboundStatusCommandHandLer : IRequestHandler<UpdateonboundStatusCommand, APIResult<int>>
    {
        private readonly ILogger<UpdateoutboundStatusCommandHandLer> _logger;
        private readonly ISqlSugarClient _db;

        public UpdateoutboundStatusCommandHandLer(
            ILogger<UpdateoutboundStatusCommandHandLer> logger,
            ISqlSugarClient db)
        {
            _logger = logger;
            _db = db;
        }

        public async Task<APIResult<int>> Handle(UpdateonboundStatusCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<int>();

            try
            {
                // 验证输入状态
                if (request.Status != 1 && request.Status != 2)
                {
                    result.Code = ResultCode.Fail;
                    result.Message = "审批状态必须为1(通过)或2(驳回)";
                    return result;
                }

                // 使用事务确保数据一致性
                var transactionResult = await _db.Ado.UseTranAsync(async () =>
                {
                    // 1. 获取出库单和关联的调拨单
                    var outboundOrder = await _db.Queryable<Wms_outbound_order>()
                        .Where(x => x.Id == request.Id)
                        .FirstAsync() ?? throw new Exception("出库单不存在");

                    var transferOrder = await _db.Queryable<Wms_Transfer_order>()
                        .Where(x => x.Id == outboundOrder.Transfer_id)
                        .FirstAsync() ?? throw new Exception("关联调拨单不存在");

                    // 2. 检查调拨单当前状态
                    if (transferOrder.Status == 2) // 如果调拨单已被驳回
                    {
                        throw new Exception("关联调拨单已被驳回，不能进行出库审批");
                    }

                    // 3. 更新出库单状态
                    outboundOrder.Status = request.Status;
                    outboundOrder.UpdateDateTime = DateTime.Now;
                    await _db.Updateable(outboundOrder)
                        .UpdateColumns(x => new { x.Status, x.UpdateDateTime })
                        .ExecuteCommandAsync();

                    // 4. 更新调拨明细的出库状态
                    await _db.Updateable<Wms_Transfer_detail>()
                        .SetColumns(it => new Wms_Transfer_detail()
                        {
                            outbound_status = request.Status,
                        })
                        .Where(it => it.Transfer_id == outboundOrder.Transfer_id)
                        .ExecuteCommandAsync();

                    // 5. 获取所有关联调拨明细
                    var transferDetails = await _db.Queryable<Wms_Transfer_detail>()
                        .Where(it => it.Transfer_id == outboundOrder.Transfer_id)
                        .ToListAsync();

                    // 6. 计算调拨主表新状态
                    int newTransferStatus = CalculateTransferStatus(transferDetails, request.Status);

                    // 7. 更新调拨主表状态
                    transferOrder.Status = newTransferStatus;
                    transferOrder.UpdateDateTime = DateTime.Now;
                    await _db.Updateable(transferOrder)
                        .UpdateColumns(x => new { x.Status, x.UpdateDateTime })
                        .ExecuteCommandAsync();

                    // 8. 记录操作日志
                    await RecordOperationLog(outboundOrder, request.Status, newTransferStatus);
                });

                result.Code = transactionResult.IsSuccess ? ResultCode.Ok : ResultCode.Fail;
                result.Message = transactionResult.IsSuccess
                    ? (request.Status == 1 ? "出库审批通过成功" : "出库审批驳回成功")
                    : $"操作失败: {transactionResult.ErrorMessage}";
            }
            catch (Exception ex)
            {
                result.Code = ResultCode.Fail;
                result.Message = $"系统错误: {ex.Message}";
                _logger.LogError(ex, "出库审批异常");
            }

            return result;
        }

        private int CalculateTransferStatus(List<Wms_Transfer_detail> details, int currentApprovalStatus)
        {
            // 如果当前审批是驳回(2)，则调拨单状态直接设为2
            if (currentApprovalStatus == 2)
            {
                return 2; // 驳回状态
            }

            // 检查出库和入库状态
            bool allOutboundApproved = details.All(d => d.outbound_status == 1);
            bool allInboundApproved = details.All(d => d.inbound_status == 1);

            // 状态判断
            if (allOutboundApproved && allInboundApproved)
            {
                return 4; // 全部完成
            }
            else if (allOutboundApproved)
            {
                return 3; // 出库完成，等待入库
            }

            return 1; // 进行中
        }

        private async Task RecordOperationLog(Wms_outbound_order order, int approvalStatus, int transferStatus)
        {
            string statusDesc = transferStatus switch
            {
                1 => "进行中",
                2 => "已驳回",
                3 => "出库完成(待入库)",
                4 => "全部完成",
                _ => "未知状态"
            };

            await _db.Insertable(new Wms_Operation_log
            {
                Transfer_id = order.Transfer_id,
                Operation_type = approvalStatus == 1 ? "出库审批通过" : "出库审批驳回",
                operator_id = order.Operator_id,
                Operation_desc = $"出库单[{order.Outbound_code}]审批，当前调拨状态: {statusDesc}",
                operation_time = DateTime.Now
            }).ExecuteCommandAsync();
        }
    }
}